home *** CD-ROM | disk | FTP | other *** search
- /* mac_path.c
- * This module includes the generic path processing code for the KA9Q package, along
- * with the file initialization code (executed only at startup).
- */
- #include <stdio.h>
- #include "global.h"
- #include "mac_files.h"
-
- #include <strings.h>
- #include <HFS.h>
-
-
- /* pathname
- * Given a working directory and an arbitrary pathname, resolve them into
- * an absolute pathname. Memory is allocated for the result, which
- * the caller must free.
- *
- * path is prefixed by a colon:
- * cd:path is returned (leading colon from path provides the cd separator)
- * path is NOT prefixed by a colon, but path contains a colon:
- * path is returned
- * path does not contain a colon:
- * cd:path is returned (colon separator is generated)
- *
- * The final absolute path is examined for ::; each such occurrence will "backup"
- * the path past the previous folder.
- */
-
- char *
- pathname(cd,path)
- char *cd; /* Current working directory */
- char *path; /* Pathname argument */
- {
- int stcpm();
- register char *buf;
- register char *ptr;
- char *dcolon();
- char * ptr2;
- int colon;
-
- /* Ignore blank args and strip any leading white space on args
- * note: send empty strings, not null pointers for a "blank" arg)
- */
-
- if (cd == NULLCHAR || path == NULLCHAR)
- return(NULLCHAR);
- while (*cd == ' ' || *cd == '\t')
- cd++;
- while (*path == ' ' || *path == '\t')
- path++;
-
- /* Allocate and initialize output buffer; user must free */
-
- if ((buf = malloc(strlen(cd) + strlen(path)+2)) == NULLCHAR) {
- printf("pathname: could not allocate memory.\n");
- return(NULLCHAR);
- }
-
- /* OK, we have:
- cd contains the working directory from our caller
- path contains the pathname to be used in the context of the above
-
- Now we must earn our keep and resolve the above three to come out with
- an absolute path name. Somebody else will actually check it to insure that
- access is allowed. */
-
- if ((colon = strpos(path,PATH_DELIM)) == 0) {
-
- /* interpret path relative to cd, path IS prefixed */
- if (strlen(cd)) { /* if we have a cd */
- sprintf(buf,"%s",cd); /* get cd in buf first */
- if (buf[strlen(buf)-1] == PATH_DELIM)
- buf[strlen(buf)-1]=NULL; /* drop last character */
- sprintf(buf,"%s%s",buf,path); /* use cd followed by path */
- }
- else {
- ptr = path; /* drop prefix in path */
- ptr++;
- sprintf(buf,"%s",ptr); /* use path less prefix*/
- }
- }
- else {
-
- /* interpret path relative to cd, path is NOT prefixed */
- if (strlen(cd) && (colon ==-1)) { /* if we have a cd and no other colons */
- sprintf(buf,"%s",cd); /* get cd in buf first */
- if (buf[strlen(buf)-1] == PATH_DELIM)
- buf[strlen(buf)-1]=NULL; /* drop last character */
- sprintf(buf,"%s:%s",buf,path); /* use cd followed by path */
- }
- else
- sprintf(buf,"%s",path); /* use path as-is */
- }
-
- /* Special case: null final path means the application root directory */
-
- if (buf[0] == NULL)
- sprintf(buf,"%s",applroot);
-
- /* now, examine what we are about to return to process double colons */
-
- if ((ptr2 = dcolon(buf)) != NULLCHAR) {
- *ptr2 = NULL; /* early-terminate buf */
- ptr2++; /* ptr2 is the second part of buf, includes 1 colon */
- if ((ptr = rindex(buf,PATH_DELIM)) == NULLCHAR)
- strcpy(buf,ptr2);
- else
- strcpy(ptr,ptr2); /* copy part after ptr2 to replace last colon */
- }
- return(buf);
- }
-
- /* find_dcolon
- * search a string for the first occurrence of a double colon.
- */
-
- char *
- dcolon(string)
- char *string;
-
- {
- char *colon,*ptr;
-
- if (string == NULLCHAR) /* can't work without data */
- return(NULLCHAR);
-
- ptr = string;
- while ((colon = index(ptr,PATH_DELIM)) != NULLCHAR) {
- colon++;
- if (*colon == NULL)
- return(NULLCHAR);
- if (*colon == PATH_DELIM) {
- colon--;
- return(colon);
- }
- ptr = colon;
- }
- /* no double colon seen, so exit */
- return(NULLCHAR);
- }
-
- /* mac_files
- * Handle the one-time initialization needed for the Macintosh file names.
- * Entry with flag == 1 will remove any MLMxxxx files from the application root
- * Entry with flag == 0 will not remove any preexisting files.
- */
-
- int
- mac_files(flag)
- int flag;
- {
- int MyVRefNum, e;
- int len;
- char buf[256],delname[256];
- char *cp,*GetPathname(),*GetVolumename();
- FILE *fp,*dir();
-
- /*
- * Get the path to the folder where we started NET and save in applroot
- * (since we are called shortly after application launch, the default working
- * directory is still set to the folder from which the application was launched).
- */
- GetVolumename(NULL,&MyVRefNum); /* get default volume reference number */
- GetPathname(applroot,MyVRefNum); /* get default path name */
-
- /* have basic path info, now generate the derivative path names */
-
- check_len(MAILSPOOL);
- sprintf(mailspool,"%s%s", applroot, MAILSPOOL);
-
- check_len(MAILQDIR);
- sprintf(mailqdir,"%s%s", applroot, MAILQDIR);
-
- check_len(ALIAS);
- sprintf(alias,"%s%s", applroot, ALIAS);
-
- check_len(TEMPPATH);
- sprintf(temppath,"%s%s", applroot, TEMPPATH);
-
- check_len(DIRBM);
- sprintf(dirbm,"%s%s", applroot, DIRBM);
-
- /*
- * all the fixed locations have been written, now run through some of the folders
- * looking for left-over files that we will delete before real startup.
- */
- if (flag == 0)
- return(0); /* first see if we are supposed to delete files */
-
- /* look for MLMxxxxx files in the application root folder */
-
- fp = dir(temppath,0); /* delete all MLM files */
- if ( fp == NULLFILE) /* Check for existence of applroot */
- {
- printf("mac_path: could not find application folder.\n");
- exit(-1);
- }
- while (fgets(buf,sizeof(buf),fp),!feof(fp)){
- if ((cp = index(buf,'\n')) == NULLCHAR)
- continue;
- *cp = NULL; /* set to null string */
- if ((cp = index(buf,'M')) != 0) {
- if (strncmp(cp,"MLM",3) == 0) {
- sprintf(delname,"%s%s",temppath,buf);
- unlink(delname);
- continue; /* Delete MLM files */
- }
- }
- }
- if (feof(fp)) {
- /* have deleted any MLM files, now close and continue */
- fclose(fp);
- unlink(dirbm); /* delete the dirbm.temp file */
- }
- return(0);
- }
-
- /* check_len
- * handle length checking for our path names in a rather specialized manner.
- */
-
- check_len(str)
- char *str;
- {
- if ( (strlen(applroot) + strlen(str)) > 255 ) {
- printf("Pathname to %s (max is 255) is to long, please shorten the path.\n", str);
- printf("The pathname you attempted was %s%s\n", applroot, str);
- exit(1);
- }
- }
-
- /* GetPathname
- *
- * This routine is passed either a working directory reference number or a volume
- * reference number, and a pointer to a string. For a WDRefNum, the full path of
- * the directory is returned (with trailing colon). For a VRefNum, the name of the
- * volume or of the default working directory on that volume will be returned
- * (with a trailing colon).
- *
- * Note that the string must be able to handle storage of up to 255 characters.
- *
- * modified from Mike Schuster, "Programming for HFS Compatibility ",
- * The Complete MacTutor, Vol. 2, pg. 87.
- *
- * (Mac C) to Light Speed C translation by Jeff Meredith 12/88
- *
- * additional documentation Edwin (Ned) Kroeker, N1EWB, 1/89
- *
- * Changes.
- * 1. removed requirement to pass size of wdrefnum(sizeof(wdrefnum)) as the
- * third parameter.
- * 2. removed need for strntac() which is not in LSC libraries.
- * 3. minor typecasting changes to match LSC prototypes.
- * 4. FSFCBLen defined in HFS.h, no need to define here. If we detect MFS only,
- * we'll handle (FSFCBLen == -1 for MFS, == length of fcb for HFS)
- * 5. All paths now return a trailing colon rather than no colon.
- */
-
- #define mfsSigWord 0xd2d7
- #define hfsSigWord 0x4244
- #define rootDirID 2
-
- char *GetPathname(pname,wdrefnum)
- char *pname;
- int wdrefnum;
- {
- HVolumeParam vp;
- WDPBRec wp;
- DirInfo dp;
- char dname[256];
- char *strtac(),*cp;
-
- /* initialize parameters */
- pname[0] = NULL;
-
- vp.ioNamePtr=(StringPtr)&dname;
- vp.ioVRefNum=wdrefnum;
- vp.ioVolIndex=0;
- wp.ioNamePtr=0L;
- wp.ioVRefNum=wdrefnum;
- wp.ioWDIndex=0;
- wp.ioWDProcID=0L;
- dp.ioNamePtr=(StringPtr)&dname;
- dp.ioFDirIndex=-1;
-
- /* get volume information */
-
- if(!PBHGetVInfo(&vp,0))
- /*
- * if MFS or HFS root, return volume name only
- */
- if(FSFCBLen==-1||vp.ioVSigWord==mfsSigWord||vp.ioVRefNum==wdrefnum) {
- strcat(pname,PtoCstr((Ptr)vp.ioNamePtr));
- strcat(pname,":");
- }
-
- /* get working directory information */
-
- else if (!PBGetWDInfo(&wp,0)) {
-
- /* traverse path from working directory to root */
- dp.ioVRefNum=wp.ioWDVRefNum;
- dp.ioDrParID=wp.ioWDDirID;
- do
- {
- /* get next node information */
- dp.ioDrDirID=dp.ioDrParID;
- if(PBGetCatInfo(&dp,0))
- break;
-
- /*concatenate node name to result*/
- strtac(pname,":");
- strtac(pname,PtoCstr((Ptr)dp.ioNamePtr));
- }
- while(dp.ioDrDirID!=rootDirID);
- }
- /* Translate entire buffer to lower case (we do comparisons later) */
- for(cp = pname;*cp != '\0';cp++)
- *cp = tolower(*cp);
- return(pname);
- }
-
- /* GetVolumename
- * This routine returns the volume name and reference number of the current default
- * volume. This routine will function on both MFS and HFS systems. The string passed
- * must be able to handle up to the maximum 255 character limit. If a null pointer
- * is passed instead of the string, only the volume reference number is returned.
- */
-
- char *GetVolumename(vname,vrefnum)
- char *vname;
- int *vrefnum;
- {
- WDPBRec DefDisk;
- char *cp;
-
- /* initialize parameters */
-
- if (vname == NULLCHAR)
- DefDisk.ioNamePtr = NULL;
- else
- DefDisk.ioNamePtr = (StringPtr) vname;
-
- if ( (PBHGetVol(&DefDisk,FALSE) ) != 0) {
- printf("Could not get the volume path name.\n");
- exit(-1);
- }
-
- *vrefnum = DefDisk.ioVRefNum; /* copy the volume reference number */
- if (DefDisk.ioNamePtr != NULL) {
- PtoCstr(vname); /* convert name string to C */
- /* Translate entire buffer to lower case (we do comparisons later) */
- for(cp = vname;*cp != '\0';cp++)
- *cp = tolower(*cp);
- return(vname);
- }
- else
- return (NULLCHAR);
- }
-